<!-- 代码已包含 CSS：使用 TailwindCSS , 安装 TailwindCSS 后方可看到布局样式效果 -->
<template>
  <div class="min-h-screen bg-gray-50">
    <!-- 主体内容 -->
    <div class="mx-auto max-w-8xl px-4 py-6">
      <!-- 标题和操作按钮 -->
      <div class="flex items-center justify-between mb-6">
        <div class="flex space-x-3">
          <el-button type="primary" class="!rounded-button whitespace-nowrap" @click="showAddDialog">
            <el-icon class="mr-1"><Plus /></el-icon>
            新增商品
          </el-button>
          <el-upload
              :on-success="uploadStudent"
              :action= "`${SERVER_ADDR}/admin/file/uploadGoods`"
              :headers="headers"
              method="post"
              name="multipartFile"
              list-type="none"
              :show-file-list="false">
            <el-button class="!rounded-button whitespace-nowrap">
              <el-icon class="mr-1"><Upload /></el-icon>
              批量导入
            </el-button>
          </el-upload>
        </div>
      </div>

      <!-- 搜索筛选区 -->
      <div class="bg-white rounded-lg shadow-sm p-4 mb-6">
        <div class="grid grid-cols-1 md:grid-cols-3 gap-4">
          <el-input
              v-model="filterForm.name"
              placeholder="搜索商品名称/ID"
              clearable
              class="!rounded-button"
              @input="getPage"
          >
            <template #prefix>
              <el-icon><Search /></el-icon>
            </template>
          </el-input>

          <el-select
              v-model="filterForm.type"
              placeholder="商品类型"
              clearable
              class="!rounded-button"
              @change="getPage"
          >
            <el-option label="全部" value="" />
            <el-option label="货品" :value="1" />
            <el-option label="菜品" :value="2" />
          </el-select>

          <el-select
              v-model="filterForm.status"
              placeholder="商品状态"
              clearable
              class="!rounded-button"
              @change="getPage"
          >
            <el-option label="全部" value="" />
            <el-option label="上架" :value="1" />
            <el-option label="下架" :value="0" />
          </el-select>

          <el-cascader
              v-model="filterForm.categoryId"
              placeholder="请选择分类"
              :options="categories"
              :props="filterProps"
              @change="getPage"
              clearable
          />
        </div>
      </div>
      <!-- 表格区域 -->
      <div class="bg-white rounded-lg shadow-sm overflow-hidden">
        <el-table
            :data="filteredProducts"
            style="width: 100%"
            border
            stripe
            v-loading="loading"
            @sort-change="handleSortChange"
        >
          <el-table-column prop="id" label="商品ID" width="100" sortable="custom" />

          <el-table-column label="商品图片" width="120">
            <template #default="{row}">
              <el-image
                  :src="`${SERVER_ADDR}/upload/${row.pic}`"
                  fit="cover"
                  class="w-16 h-16 rounded"
              />
            </template>
          </el-table-column>

          <el-table-column prop="name" label="商品名称" width="180" />

          <el-table-column label="商品类型" width="120">
            <template #default="{row}">
              <el-tag :type="row.type === 1 ? '' : 'success'">
                {{ row.type === 1 ? '货品' : '菜品' }}
              </el-tag>
            </template>
          </el-table-column>

          <el-table-column prop="count" label="库存" width="120" sortable="custom">
            <template #default="{row}">
              <span :class="{'text-yellow-500': row.count < 10}">{{ row.count }}</span>
            </template>
          </el-table-column>

          <el-table-column label="价格" width="180">
            <template #default="{row}">
              <div class="flex flex-col">
                <span class="text-gray-400 line-through text-sm">¥{{ row.price }}</span>
                <span class="text-red-500 font-medium">¥{{ row.realPrice }}</span>
              </div>
            </template>
          </el-table-column>

          <el-table-column label="分类" width="150">
            <template #default="{row}">
              <el-tag v-if="row.categoryIds" type="primary">
                {{ row.categoryIds }}
              </el-tag>
              <el-tag v-if="row.categoryId !== -1" type="primary">
                {{ row.category.name }}
              </el-tag>
            </template>
          </el-table-column>

          <el-table-column label="评分" width="180">
            <template #default="{row}">
              <el-rate
                  v-model="row.star"
                  disabled
                  show-score
                  score-template="{value}分"
              />
            </template>
          </el-table-column>

          <el-table-column label="状态" width="80">
            <template #default="{row}">
              <el-tag :type="row.status ? 'success' : 'danger'">
                {{ row.status ? '上架' : '下架' }}
              </el-tag>
            </template>
          </el-table-column>

          <el-table-column label="操作" width="180" fixed="right">
            <template #default="{row}">
              <div class="flex space-x-2">
                <el-button size="small" @click="showDetail(row)">
                  <el-icon><View /></el-icon>
                </el-button>
                <el-button size="small" type="primary" @click="editProduct(row.id)">
                  <el-icon><Edit /></el-icon>
                </el-button>
                <el-button size="small" type="danger" @click="confirmDelete(row)">
                  <el-icon><Delete /></el-icon>
                </el-button>
              </div>
            </template>
          </el-table-column>
        </el-table>

        <!-- 分页 -->
        <div class="p-4 flex justify-end">
          <el-pagination
              v-model:current-page="currentPage"
              v-model:page-size="pageSize"
              :page-sizes="[5, 10, 20, 50, 100]"
              :total="total"
              layout="total, sizes, prev, pager, next, jumper"
              @size-change="handleSizeChange"
              @current-change="handleCurrentChange"
          />
        </div>
      </div>
    </div>

    <!-- 新增/编辑对话框 -->
    <el-dialog
        v-model="dialogVisible"
        :title="isEdit ? '编辑餐品' : '新增餐品'"
        width="50%"
    >
      <el-form :model="form" label-width="100px" :rules="rules" ref="formRef">
        <el-form-item label="商品名称" prop="name">
          <el-input v-model="form.name" placeholder="请输入商品名称" />
        </el-form-item>

        <el-form-item label="商品类型" prop="type">
          <el-radio-group v-model="form.type">
            <el-radio :label="1">货品</el-radio>
            <el-radio :label="2">菜品</el-radio>
          </el-radio-group>
        </el-form-item>

        <el-form-item label="商品分类" prop="category_id">
          <el-cascader
              v-if="form.type === 2"
              v-model="form.categoryIds"
              placeholder="请选择分类"
              :options="categories"
              :props="props"
          />
          <el-cascader
              v-else
              v-model="form.categoryId"
              placeholder="请选择分类"
              :options="categories"
              :props="filterProps"
              clearable
          />
        </el-form-item>

        <el-form-item label="商品图片" prop="image">
          <el-upload
              class="avatar-uploader"
              :action="`${SERVER_ADDR}/admin/file/upload`"
              name="pic"
              :headers="headers"
              :show-file-list="false"
              :on-success="handleImageSuccess"
              :before-upload="beforeImageUpload"
          >
            <img v-if="imageUrl" :src="imageUrl" class="avatar" />
            <el-icon v-else class="avatar-uploader-icon"><Plus /></el-icon>
          </el-upload>
        </el-form-item>

        <el-form-item label="标价" prop="price">
          <el-input-number v-model="form.price" :min="0" :precision="2" />
        </el-form-item>

        <el-form-item label="实际价格" prop="real_price">
          <el-input-number v-model="form.realPrice" :min="0" :precision="2" />
        </el-form-item>

        <el-form-item label="库存" prop="count">
          <el-input-number v-model="form.count" :min="0" />
        </el-form-item>

        <el-form-item label="评分" prop="star">
          <el-rate v-model="form.star" allow-half />
        </el-form-item>

        <el-form-item label="商品状态" prop="status">
          <el-switch v-model="form.status"
                     active-value="1"
                     inactive-value="0"
                     active-text="上架"
                     inactive-text="下架" />
        </el-form-item>

        <el-form-item label="商品描述" prop="description">
          <el-input v-model="form.description" type="textarea" :rows="3" />
        </el-form-item>
      </el-form>

      <template #footer>
        <span class="dialog-footer">
          <el-button @click="dialogVisible = false">取消</el-button>
          <el-button type="primary" @click="submitForm">确定</el-button>
        </span>
      </template>
    </el-dialog>

    <!-- 详情对话框 -->
    <el-dialog
        v-model="detailVisible"
        title="商品详情"
        width="50%"
    >
      <div v-if="currentProduct" class="space-y-4">
        <div class="flex items-start space-x-6">
          <el-image
              :src="`${SERVER_ADDR}/upload/${currentProduct.pic}`"
              class="w-48 h-48 rounded-lg"
          />
          <div class="flex-1">
            <h3 class="text-xl font-bold">{{ currentProduct.name }}</h3>
            <div class="mt-2 flex items-center space-x-4">
              <el-tag :type="currentProduct.type === 1 ? '' : 'success'">
                {{ currentProduct.type === 1 ? '货品' : '菜品' }}
              </el-tag>
              <el-tag :type="currentProduct.status ? 'success' : 'danger'">
                {{ currentProduct.status ? '上架' : '下架' }}
              </el-tag>
            </div>
            <div class="mt-4 grid grid-cols-2 gap-4">
              <div>
                <p class="text-gray-500 text-sm">商品分类</p>
                <p>{{ currentProduct.categoryId }}</p>
              </div>
              <div>
                <p class="text-gray-500 text-sm">库存</p>
                <p :class="{'text-yellow-500': currentProduct.count < 10}">{{ currentProduct.count }}</p>
              </div>
              <div>
                <p class="text-gray-500 text-sm">标价</p>
                <p class="text-gray-400 line-through">¥{{ currentProduct.price }}</p>
              </div>
              <div>
                <p class="text-gray-500 text-sm">实际价格</p>
                <p class="text-red-500 font-medium">¥{{ currentProduct.realPrice }}</p>
              </div>
            </div>
            <div class="mt-4">
              <p class="text-gray-500 text-sm">评分</p>
              <el-rate
                  v-model="currentProduct.star"
                  disabled
                  show-score
                  score-template="{value} 分"
              />
            </div>
          </div>
        </div>

        <div class="mt-6">
          <h4 class="font-medium text-gray-900">商品描述</h4>
          <p class="mt-2 text-gray-600">{{ currentProduct.description || '暂无描述' }}</p>
        </div>
      </div>

      <template #footer>
        <span class="dialog-footer">
          <el-button @click="detailVisible = false">关闭</el-button>
        </span>
      </template>
    </el-dialog>
  </div>
</template>

<script lang="js" setup>
import { ref, computed, onMounted, nextTick } from 'vue';
import { ElMessage, ElMessageBox } from 'element-plus';
import {
  Plus,
  Upload,
  Star,
  Search,
  View,
  Edit,
  Delete, UploadFilled
} from '@element-plus/icons-vue';
import goodsApi from "@/api/admin/goodsApi.js";
import categoryApi from "@/api/admin/categoryApi.js";
import {useTokenStore} from "@/stores/token.js";

//服务器路径
const SERVER_ADDR = ref(import.meta.env.VITE_SERVER_ADDR);
const tokenStore = useTokenStore();
//上传图片
const headers = computed(() => {
  let token = tokenStore.tokenStr;
  return {
    token
  }
})
// 分类数据以及配置
const props = {
  value: 'id',
  label: 'name',
  children: 'children',
  multiple: true,
  emitPath: false,
  collapseTags: true,
  collapseTagsTooltip: true,
  maxCollapseTags: 3,
  clearable: true
};

const filterProps = {
  value: 'id',
  label: 'name',
  children: 'children',
  emitPath: false,
  clearable: true
};
const categories = ref();

// 表格相关状态
const loading = ref(false);
const currentPage = ref(1);
const pageSize = ref(5);
const total = ref('');
const sortProp = ref('');
const sortOrder = ref('');

// 筛选条件
const filterForm = ref({
  name: '',
  type: '',
  status: '',
  categoryId: '',
});


// 对话框状态
const dialogVisible = ref(false);
const detailVisible = ref(false);
const isEdit = ref(false);
const currentProduct = ref(null);
const formRef = ref();

// 表单数据
const form = ref({
  id: 0,
  name: '',
  pic: '',
  type: 2,
  count: 0,
  price: 0,
  realPrice: 0,
  categoryId: -1,
  categoryIds: 1,
  description: '',
  star: 5,
  status: 1,
});
// 分页数据
const pageData = ref();
// 表单验证规则
const rules = ref({
  name: [{ required: true, message: '请输入商品名称', trigger: 'blur' }],
  type: [{ required: true, message: '请选择商品类型', trigger: 'change' }],
  categoryId: [{ required: true, message: '请选择商品分类', trigger: 'change' }],
  price: [{ required: true, message: '请输入标价', trigger: 'blur' }],
  realPrice: [{ required: true, message: '请输入实际价格', trigger: 'blur' }],
  count: [{ required: true, message: '请输入库存', trigger: 'blur' }]
});
// 获取所有分类数据
const getCategory = () => {
  let category = {
    parentId: 0,
    categoryType: 2,
  };
  categoryApi.selectByPage(null, null, category)
      .then(resp => {
        if (resp.data && resp.data.length > 0) {
          categories.value = resp.data;
        } else {
          console.error('分类数据为空或未正确返回');
        }
      })
      .catch(error => {
        console.error('获取分类数据失败:', error);
      });
};
// 获取分页数据
const getPage = ()=>{
  goodsApi.selectByPage(currentPage.value, pageSize.value, filterForm.value)
      .then(resp => {
        pageData.value = resp.data;
        total.value = pageData.value.total;
      })
};
// 计算菜品列表
const filteredProducts = computed(() => {
  // 保证pageData.value存在
  if (!pageData.value) {
    return [];
  }
  let result = pageData.value.data;

  // 分类处理
  if (!categories.value) {
    return [];
  }
  categories.value.forEach(item => {
    item.children.forEach(item => {
      const children = item;
      result.forEach(item => {
        let newItem = item;
        if (item.categoryList != null) {
          newItem.categoryIds = [];
          item.categoryList.forEach(item => {
            newItem.categoryIds.push(item.name);
          })
          var join = newItem.categoryIds.join(',');
          newItem.categoryIds = join;

        }
        return newItem
      })

    })
  });
  // 排序
  if (sortProp.value && sortOrder.value) {
    result.sort((a, b) => {
      const valA = a[sortProp.value];
      const valB = b[sortProp.value];
      if (sortOrder.value === 'ascending') {
        return compareValues(valA,valB)
      } else {
        return compareValues(valB,valA)
      }
    });
  }
  return result;
});
// 通用排序规则
const compareValues = (a, b)=>{
  // 数字类型比较
  if (typeof a === 'number' && typeof b === 'number') {
    return a - b;
  }

  // 日期类型比较
  if (a instanceof Date && b instanceof Date) {
    return a.getTime() - b.getTime();
  }

  // 字符串类型（支持中文）
  return String(a).localeCompare(String(b), 'zh');
}
// 分页数据
const pagedProducts = computed(() => {
  const start = (currentPage.value - 1) * pageSize.value;
  const end = start + pageSize.value;
  console.log(start)
  console.log(end)
  return filteredProducts.value.slice(start, end);
});
// 显示新增对话框
const showAddDialog = () => {
  isEdit.value = false;
  form.value = {
    id: 0,
    name: '',
    pic: '',
    type: 2,
    count: 0,
    price: 0,
    realprice: 0,
    categoryId: 1,
    description: '',
    star: 5,
    status: 1,
    image: ''
  };
  dialogVisible.value = true;
  nextTick(() => {
    formRef.value?.clearValidate();
  });
};

// 编辑商品
const editProduct = (id) => {
  goodsApi.selectByID(id)
      .then(resp => {
        const product = resp.data;
        if (product) {
          form.value = product;
          // 如何categoryId是null就赋值为-1
          if (resp.data.category == null) {
            form.value.categoryId = -1;
          }
          form.value.categoryIds = product.categoryList.map(item => item.id);
          imageUrl.value = `${SERVER_ADDR.value}/upload/${product.pic}`
          isEdit.value = true;
          dialogVisible.value = true;
          nextTick(() => {
            formRef.value?.clearValidate();
          });
        } else {
          ElMessage.error('商品不存在');
        }
      })
      .catch(error => {
        ElMessage.error('商品不存在');
      });

};

// 提交表单
const submitForm = () => {
  // 判断是否是新增还是编辑
  if (isEdit.value) {
    goodsApi.update(form.value)
        .then(resp => {
          if (resp.code === 10000){
            dialogVisible.value = false;
            // 重置form里面的数据
            form.value = {
              id: 0,
              name: '',
              pic: '',
              type: 2,
              count: 0,
              price: 0,
              realPrice: 0,
              categoryIds: 1,
              description: '',
              star: 5,
              status: 1,
            }
            imageUrl.value = '';
            ElMessage.success(resp.msg)
            getPage();
          }else {
            ElMessage.error(resp.msg)
          }
        })
  }else {
    goodsApi.insert(form.value)
        .then(resp => {
          if (resp.code === 10000){
            dialogVisible.value = false;
            getPage();
            // 重置form里面的数据
            form.value = {
              id: 0,
              name: '',
              pic: '',
              type: 2,
              count: 0,
              price: 0,
              realPrice: 0,
              categoryIds: 1,
              description: '',
              star: 5,
              status: 1,
            }
            imageUrl.value = '';
            ElMessage.success(resp.msg)
          }else {
            ElMessage.error(resp.msg)
          }
        })
  }
};

// 删除商品
const confirmDelete = (product) => {
  ElMessageBox.confirm(
      `确定要删除商品 "${product.name}" 吗？`,
      '提示',
      {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }
  ).then(() => {
    goodsApi.delete(product.id)
        .then(resp => {
          if (resp.code === 10000){
            ElMessage.success('删除成功');
            getPage();
          }else {
            ElMessage.error(resp.msg)
          }
        })
    ElMessage.success('删除成功');
  }).catch(() => {
    // 取消删除
  });
};

// 显示详情
const showDetail = (product) => {
  currentProduct.value = product;
  detailVisible.value = true;
};

// 批量导入
const uploadStudent = (resp) => {
  if (resp.code === 10000) {
    ElMessage.success(resp.msg)
  } else {
    ElMessage.error(resp.msg)
  }
}
// 分页大小变化
const handleSizeChange = (val) => {
  pageSize.value = val;
  getPage();
};

// 当前页变化
const handleCurrentChange = (val) => {
  currentPage.value = val;
  getPage();
};

// 排序变化
const handleSortChange = ( {prop, order} ) => {
  sortProp.value = prop;
  sortOrder.value = order;
};
const imageUrl = ref("");
// 图片上传处理
const handleImageSuccess = (response, file) => {
  if (response.code === 10000) {
    ElMessage.success('上传成功');
    imageUrl.value = `${SERVER_ADDR.value}/upload/${response.data}`;
    form.value.pic = response.data;
  }

};

const beforeImageUpload = (file) => {
  const isJPG = file.type === 'image/jpeg' || file.type === 'image/png';
  const isLt2M = file.size / 1024 / 1024 < 2;

  if (!isJPG) {
    ElMessage.error('上传图片只能是 JPG/PNG 格式!');
  }
  if (!isLt2M) {
    ElMessage.error('上传图片大小不能超过 2MB!');
  }
  return isJPG && isLt2M;
};

getPage();
getCategory();
</script>

<style scoped>
.avatar-uploader {
  border: 1px dashed #d9d9d9;
  border-radius: 6px;
  cursor: pointer;
  position: relative;
  overflow: hidden;
  width: 120px;
  height: 120px;
}

.avatar-uploader:hover {
  border-color: #409eff;
}

.avatar-uploader-icon {
  font-size: 28px;
  color: #8c939d;
  width: 120px;
  height: 120px;
  line-height: 120px;
  text-align: center;
}

.avatar {
  width: 120px;
  height: 120px;
  display: block;
  object-fit: cover;
}

:deep(.el-table .cell) {
  padding-left: 8px;
  padding-right: 8px;
}

:deep(.el-table th.el-table__cell) {
  background-color: #f5f5f5;
}

:deep(.el-table--striped .el-table__body tr.el-table__row--striped td.el-table__cell) {
  background-color: #fafafa;
}

:deep(.el-table .el-table__body tr:hover > td.el-table__cell) {
  background-color: #f0f7ff;
}
</style>
